﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace PersonaLibrary
{
    internal static class AlphabetExpression
    {
        public static LambdaExpression CreateExpression(CustomProperties.PropertiesItem item, Type type)
        {
            if (item.IsAlphabetFilter)
                return CreateExpression(type, item.IsAllowRegister, item.AlphabetFilterProperty,
                                        item.AlphabetFilterValue);

            return null;
        }

        public static LambdaExpression CreateExpression<T>(CustomProperties.PropertiesItem item)
        {
            if (item.IsAlphabetFilter)
                return CreateExpression(typeof (T), item.IsAllowRegister, item.AlphabetFilterProperty,
                                        item.AlphabetFilterValue);

            return null;
        }

        public static LambdaExpression CreateExpression(Type itemType, bool isAllowRegister, string propertyName, string propertyValue)
        {
            var param = Expression.Parameter(itemType, "x");
            Expression property = null;
            if (itemType.GetProperty(propertyName) != null)
                property = Expression.Property(param, propertyName);
            else
            {
                if (propertyName.Split(".".ToCharArray()).Length > 1)
                {
                    foreach (string propName in propertyName.Split(".".ToCharArray()))
                    {
                        if (property == null)
                            property = Expression.Property(param, propName);
                        else
                            property = Expression.Property(property, propName);
                    }
                }
                else
                    property = Expression.Call(param, typeof(object).GetMethod("ToString", new Type[] { }));
            }
            var equalConst = Expression.Constant(propertyValue);

            LambdaExpression expression;
            if (isAllowRegister)
            {
                var method = Expression.Call(property, typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }), equalConst);
                expression = Expression.Lambda(method, param);
            }
            else
            {
                var firstMethod = Expression.Call(property, typeof(string).GetMethod("ToUpper", new Type[] { }));
                if(equalConst.Value == null)
                    equalConst = Expression.Constant(" ");
                var secondMethod = Expression.Call(firstMethod, typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }), equalConst);
                expression = Expression.Lambda(secondMethod, param);
            }
            return expression;
        }
    }
}
